/**
 * 
 */
package freedom.needle.tps;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import freedom.needle.entity.TpsInfo;
import freedom.needle.enums.TpsInfoStateEnum;
import freedom.needle.util.WeblogicUtil;

/**
 * @author charlie
 *
 */
public class TpsWindow {
	
	final Lock lock = new ReentrantLock();
	private boolean open = false;
	private Integer taskNo;
	private String taskName;
	private long lastCount;
	private long count;
	private Date time;
	

	/**
	 * @param taskNo
	 * @param taskName
	 * @param lastCount
	 * @param count
	 * @param time
	 * @param lock
	 */
	public TpsWindow(Integer taskNo, String taskName) {
		super();
		this.taskNo = taskNo;
		this.taskName = taskName;
		this.lastCount = 0L;
		this.count = 0L;
		this.time = new Date();
	}

	public void inc() {
		lock.lock();
		try {
			count++;
		} finally {
			lock.unlock();
		}
	}
	
	public TpsInfo snapshoot() {
		lock.lock();
		try {
			BigDecimal inc = new BigDecimal(count - lastCount);
			Date now = new Date();
			BigDecimal spend = new BigDecimal(now.getTime() - time.getTime());
			BigDecimal tps = inc.multiply(new BigDecimal(1000)).divide(spend,6, RoundingMode.HALF_DOWN);
			TpsInfo tpsInfo = new TpsInfo(taskNo, taskName, now, tps, WeblogicUtil.getId());
			tpsInfo.setState(TpsInfoStateEnum.FRESH);
			lastCount = count;
			time = now;
			return tpsInfo;
		} finally {
			lock.unlock();
		}
		
	}

	/**
	 * @return the taskNo
	 */
	public Integer getTaskNo() {
		return taskNo;
	}

	/**
	 * @return the taskName
	 */
	public String getTaskName() {
		return taskName;
	}

	/**
	 * @return the lastCount
	 */
	public long getLastCount() {
		return lastCount;
	}

	/**
	 * @return the count
	 */
	public long getCount() {
		return count;
	}

	/**
	 * @return the time
	 */
	public Date getTime() {
		return time;
	}

	/**
	 * @return the open
	 */
	public boolean isOpen() {
		return open;
	}

	/**
	 * @param open the open to set
	 */
	public void setOpen(boolean open) {
		this.open = open;
	}
	

}
